#include "wingbot_timer.h"
#include "wingbot_tick.h"

/**
* @brief TIM3定时器中断初始化，初始化完毕后定时器马上使能，并触发一次中断
* @param arr:    自动装载寄存器
         psc:    预分频器寄存器
*/
void timer_int_init(TIM_TypeDef* TIMx, u16 arr, u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    if(TIMx == TIM2)RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    if(TIMx == TIM3)RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);        //时钟使能
    if(TIMx == TIM4)RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
    
    TIM_UpdateDisableConfig(TIMx, ENABLE);                     //禁止更新事件，否则在更新psc，arr值的时候也会产生中断
    
    //定时器TIMx初始化
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;     //预分频器不分频
    TIM_TimeBaseStructure.TIM_Prescaler = psc;                  //分频系数 72000000/7200=10000
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数
    TIM_TimeBaseStructure.TIM_Period = arr;                     //预装值     10/10000=1ms;            
    TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure);    
    TIM_PrescalerConfig(TIMx, psc, TIM_PSCReloadMode_Immediate); //预分频值立即生效
    //中断优先级NVIC设置
    if(TIMx == TIM2)
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;             //TIM2中断
    else if(TIMx == TIM3)
        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;             //TIM3中断
    else if(TIMx == TIM4)
        NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;             //TIM4中断
    
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;   //先占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;          //从优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //IRQ通道被使能
    NVIC_Init(&NVIC_InitStructure);                             //初始化NVIC寄存器

    TIM_UpdateDisableConfig(TIMx, DISABLE);                     //使能更新事件
    TIM_ITConfig(TIMx,TIM_IT_Update, ENABLE);                   //使能指定的TIM3中断,允许更新中断
    TIM_Cmd(TIMx, ENABLE);                                      //使能TIMx
}

/**
* @brief 设定一个微秒定时器
* @param TIMx:   定时器名称
         dt:     等待多少微秒
*/
void set_us_timer(TIM_TypeDef* TIMx, uint8_t dt)
{
    timer_int_init(TIMx, dt, SystemCoreClock/1000000);
}

/**
* @brief 设定一个毫秒定时器
* @param TIMx:   定时器名称
         dt:     等待多少毫秒
*/
void set_ms_timer(TIM_TypeDef* TIMx, uint8_t dt)
{
    if(TIMx == TIM2)
        wing_timer_start(TIM2);
    timer_int_init(TIMx, dt*10, SystemCoreClock/10000);
}
